package com.geo.service.business;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.geo.entity.Business;
import com.geo.entity.User;
import com.geo.business.mapper.BusinessMapper;
import com.geo.service.cache.CacheService;
import com.geo.service.sync.DataSyncService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * 商家管理服务
 * 实现企业注册、信息管理、认证审核功能
 * 
 * @author GEO Team
 * @version 1.0.0
 */
@Slf4j
@Service
public class BusinessManagementService extends ServiceImpl<BusinessMapper, Business> {
    
    private static final Logger log = LoggerFactory.getLogger(BusinessManagementService.class);
    
    @Autowired
    private CacheService cacheService;
    
    @Autowired
    private DataSyncService dataSyncService;
    
    /**
     * ===========================================
     * 企业注册相关方法
     * ===========================================
     */
    
    /**
     * 企业注册
     * @param business 企业信息
     * @param userId 注册用户ID
     * @return 注册结果
     */
    @Transactional(rollbackFor = Exception.class)
    public BusinessRegistrationResult registerBusiness(Business business, Long userId) {
        try {
            // 验证企业信息
            validateBusinessInfo(business);
            
            // 检查企业名称是否已存在
            if (isBusinessNameExists(business.getBusinessName())) {
                return BusinessRegistrationResult.failure("企业名称已存在");
            }
            
            // 检查统一社会信用代码是否已存在
            if (StringUtils.hasText(business.getCreditCode()) && 
                isCreditCodeExists(business.getCreditCode())) {
                return BusinessRegistrationResult.failure("统一社会信用代码已存在");
            }
            
            // 生成企业编码
            business.setBusinessCode(generateBusinessCode());
            
            // 设置初始状态
            business.setVerificationStatus(Business.VerificationStatus.PENDING);
            business.setAccountStatus(Business.AccountStatus.ACTIVE);
            business.setSubscriptionPlan(Business.SubscriptionPlan.TRIAL);
            business.setSubscriptionStartTime(LocalDateTime.now());
            business.setSubscriptionEndTime(LocalDateTime.now().plusDays(30)); // 30天试用期
            
            // 设置默认限制
            business.setApiLimitMonthly(10000L);
            business.setContentLimitMonthly(1000L);
            business.setKeywordLimit(100);
            business.setDataRetentionDays(90);
            
            // 设置创建信息
            business.setCreateBy(userId.toString());
            business.setLastActiveTime(LocalDateTime.now());
            
            // 保存企业信息
            save(business);
            
            // 清除相关缓存
            clearBusinessCache(business.getId().toString());
            
            log.info("企业注册成功: businessId={}, businessName={}", 
                    business.getId(), business.getBusinessName());
            
            return BusinessRegistrationResult.success(business);
            
        } catch (Exception e) {
            log.error("企业注册失败: businessName={}", business.getBusinessName(), e);
            return BusinessRegistrationResult.failure("注册失败: " + e.getMessage());
        }
    }
    
    /**
     * 验证企业信息
     * @param business 企业信息
     */
    private void validateBusinessInfo(Business business) {
        if (!StringUtils.hasText(business.getBusinessName())) {
            throw new IllegalArgumentException("企业名称不能为空");
        }
        
        if (!StringUtils.hasText(business.getContactName())) {
            throw new IllegalArgumentException("联系人姓名不能为空");
        }
        
        if (!StringUtils.hasText(business.getContactPhone())) {
            throw new IllegalArgumentException("联系电话不能为空");
        }
        
        if (!StringUtils.hasText(business.getContactEmail())) {
            throw new IllegalArgumentException("联系邮箱不能为空");
        }
        
        // 验证邮箱格式
        if (!isValidEmail(business.getContactEmail())) {
            throw new IllegalArgumentException("邮箱格式不正确");
        }
    }
    
    /**
     * 生成企业编码
     * @return 企业编码
     */
    private String generateBusinessCode() {
        return "BIZ" + System.currentTimeMillis() + 
               UUID.randomUUID().toString().substring(0, 6).toUpperCase();
    }
    
    /**
     * ===========================================
     * 企业信息管理相关方法
     * ===========================================
     */
    
    /**
     * 更新企业信息
     * @param businessId 企业ID
     * @param business 更新的企业信息
     * @param userId 操作用户ID
     * @return 更新结果
     */
    @Transactional(rollbackFor = Exception.class)
    public BusinessUpdateResult updateBusinessInfo(Long businessId, Business business, Long userId) {
        try {
            Business existingBusiness = getById(businessId);
            if (existingBusiness == null) {
                return BusinessUpdateResult.failure("企业不存在");
            }
            
            // 更新基本信息
            updateBasicInfo(existingBusiness, business);
            
            // 设置更新信息
            existingBusiness.setUpdateBy(userId.toString());
            existingBusiness.setLastActiveTime(LocalDateTime.now());
            
            // 保存更新
            updateById(existingBusiness);
            
            // 清除缓存
            clearBusinessCache(businessId.toString());
            
            log.info("企业信息更新成功: businessId={}", businessId);
            
            return BusinessUpdateResult.success(existingBusiness);
            
        } catch (Exception e) {
            log.error("企业信息更新失败: businessId={}", businessId, e);
            return BusinessUpdateResult.failure("更新失败: " + e.getMessage());
        }
    }
    
    /**
     * 更新基本信息
     * @param existing 现有企业信息
     * @param updated 更新的企业信息
     */
    private void updateBasicInfo(Business existing, Business updated) {
        if (StringUtils.hasText(updated.getBusinessName())) {
            existing.setBusinessName(updated.getBusinessName());
        }
        if (StringUtils.hasText(updated.getShortName())) {
            existing.setShortName(updated.getShortName());
        }
        if (StringUtils.hasText(updated.getEnglishName())) {
            existing.setEnglishName(updated.getEnglishName());
        }
        if (StringUtils.hasText(updated.getDescription())) {
            existing.setDescription(updated.getDescription());
        }
        if (StringUtils.hasText(updated.getWebsite())) {
            existing.setWebsite(updated.getWebsite());
        }
        if (StringUtils.hasText(updated.getIndustry())) {
            existing.setIndustry(updated.getIndustry());
        }
        if (StringUtils.hasText(updated.getCompanySize())) {
            existing.setCompanySize(updated.getCompanySize());
        }
        if (StringUtils.hasText(updated.getContactName())) {
            existing.setContactName(updated.getContactName());
        }
        if (StringUtils.hasText(updated.getContactPhone())) {
            existing.setContactPhone(updated.getContactPhone());
        }
        if (StringUtils.hasText(updated.getContactEmail())) {
            existing.setContactEmail(updated.getContactEmail());
        }
        if (StringUtils.hasText(updated.getCity())) {
            existing.setCity(updated.getCity());
        }
        if (StringUtils.hasText(updated.getProvince())) {
            existing.setProvince(updated.getProvince());
        }
        if (StringUtils.hasText(updated.getCountry())) {
            existing.setCountry(updated.getCountry());
        }
    }
    
    /**
     * 获取企业详细信息
     * @param businessId 企业ID
     * @return 企业信息
     */
    public Business getBusinessDetail(Long businessId) {
        // 先从缓存获取
        String cacheKey = "business:info:" + businessId;
        Business business = cacheService.get(cacheKey, Business.class);
        
        if (business == null) {
            // 从数据库获取
            business = getById(businessId);
            if (business != null) {
                // 缓存企业信息
                cacheService.cacheBusinessInfo(businessId.toString(), business);
            }
        }
        
        return business;
    }
    
    /**
     * 分页查询企业列表
     * @param pageNum 页码
     * @param pageSize 页面大小
     * @param searchKeyword 搜索关键词
     * @param status 账户状态
     * @param verificationStatus 验证状态
     * @return 企业列表
     */
    public IPage<Business> getBusinessPage(int pageNum, int pageSize, String searchKeyword, 
                                          String status, String verificationStatus) {
        Page<Business> page = new Page<>(pageNum, pageSize);
        
        LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
        
        // 搜索条件
        if (StringUtils.hasText(searchKeyword)) {
            queryWrapper.and(wrapper -> wrapper
                .like(Business::getBusinessName, searchKeyword)
                .or().like(Business::getBusinessCode, searchKeyword)
                .or().like(Business::getContactName, searchKeyword)
                .or().like(Business::getContactEmail, searchKeyword));
        }
        
        // 状态过滤
        if (StringUtils.hasText(status)) {
            queryWrapper.eq(Business::getAccountStatus, status);
        }
        
        if (StringUtils.hasText(verificationStatus)) {
            queryWrapper.eq(Business::getVerificationStatus, verificationStatus);
        }
        
        // 按创建时间倒序
        queryWrapper.orderByDesc(Business::getCreateTime);
        
        return page(page, queryWrapper);
    }
    
    /**
     * ===========================================
     * 认证审核相关方法
     * ===========================================
     */
    
    /**
     * 提交认证申请
     * @param businessId 企业ID
     * @param certificationFiles 认证文件
     * @param userId 操作用户ID
     * @return 提交结果
     */
    @Transactional(rollbackFor = Exception.class)
    public VerificationResult submitVerification(Long businessId, List<String> certificationFiles, Long userId) {
        try {
            Business business = getById(businessId);
            if (business == null) {
                return VerificationResult.failure("企业不存在");
            }
            
            // 检查是否已通过认证
            if (Business.VerificationStatus.VERIFIED.equals(business.getVerificationStatus())) {
                return VerificationResult.failure("企业已通过认证");
            }
            
            // 更新认证文件
            if (certificationFiles != null && !certificationFiles.isEmpty()) {
                business.setCertificationFiles(String.join(",", certificationFiles));
            }
            
            // 设置为待审核状态
            business.setVerificationStatus(Business.VerificationStatus.PENDING);
            business.setUpdateBy(userId.toString());
            
            updateById(business);
            
            // 清除缓存
            clearBusinessCache(businessId.toString());
            
            log.info("企业认证申请提交成功: businessId={}", businessId);
            
            return VerificationResult.success("认证申请提交成功，等待审核");
            
        } catch (Exception e) {
            log.error("提交认证申请失败: businessId={}", businessId, e);
            return VerificationResult.failure("提交失败: " + e.getMessage());
        }
    }
    
    /**
     * 审核企业认证
     * @param businessId 企业ID
     * @param approved 是否通过
     * @param remark 审核备注
     * @param reviewerId 审核人ID
     * @return 审核结果
     */
    @Transactional(rollbackFor = Exception.class)
    public VerificationResult reviewVerification(Long businessId, boolean approved, 
                                               String remark, Long reviewerId) {
        try {
            Business business = getById(businessId);
            if (business == null) {
                return VerificationResult.failure("企业不存在");
            }
            
            // 设置审核结果
            business.setVerificationStatus(approved ? 
                Business.VerificationStatus.VERIFIED : Business.VerificationStatus.REJECTED);
            business.setVerificationTime(LocalDateTime.now());
            business.setVerificationRemark(remark);
            business.setUpdateBy(reviewerId.toString());
            
            // 如果审核通过，升级订阅计划
            if (approved) {
                upgradeSubscriptionPlan(business);
            }
            
            updateById(business);
            
            // 清除缓存
            clearBusinessCache(businessId.toString());
            
            log.info("企业认证审核完成: businessId={}, approved={}", businessId, approved);
            
            return VerificationResult.success(approved ? "认证审核通过" : "认证审核未通过");
            
        } catch (Exception e) {
            log.error("企业认证审核失败: businessId={}", businessId, e);
            return VerificationResult.failure("审核失败: " + e.getMessage());
        }
    }
    
    /**
     * 升级订阅计划
     * @param business 企业信息
     */
    private void upgradeSubscriptionPlan(Business business) {
        // 认证通过后升级到基础版
        business.setSubscriptionPlan(Business.SubscriptionPlan.BASIC);
        business.setSubscriptionEndTime(LocalDateTime.now().plusYears(1)); // 延长一年
        
        // 提升限制
        business.setApiLimitMonthly(50000L);
        business.setContentLimitMonthly(5000L);
        business.setKeywordLimit(500);
        business.setDataRetentionDays(365);
    }
    
    /**
     * ===========================================
     * 订阅管理相关方法
     * ===========================================
     */
    
    /**
     * 升级订阅计划
     * @param businessId 企业ID
     * @param newPlan 新计划
     * @param userId 操作用户ID
     * @return 升级结果
     */
    @Transactional(rollbackFor = Exception.class)
    public SubscriptionResult upgradeSubscription(Long businessId, String newPlan, Long userId) {
        try {
            Business business = getById(businessId);
            if (business == null) {
                return SubscriptionResult.failure("企业不存在");
            }
            
            // 更新订阅计划
            business.setSubscriptionPlan(newPlan);
            business.setSubscriptionStartTime(LocalDateTime.now());
            business.setSubscriptionEndTime(calculateEndTime(newPlan));
            business.setUpdateBy(userId.toString());
            
            // 更新服务限制
            updateServiceLimits(business, newPlan);
            
            updateById(business);
            
            // 清除缓存
            clearBusinessCache(businessId.toString());
            
            log.info("订阅计划升级成功: businessId={}, newPlan={}", businessId, newPlan);
            
            return SubscriptionResult.success("订阅计划升级成功");
            
        } catch (Exception e) {
            log.error("订阅计划升级失败: businessId={}", businessId, e);
            return SubscriptionResult.failure("升级失败: " + e.getMessage());
        }
    }
    
    /**
     * 计算订阅结束时间
     * @param plan 订阅计划
     * @return 结束时间
     */
    private LocalDateTime calculateEndTime(String plan) {
        LocalDateTime now = LocalDateTime.now();
        return switch (plan) {
            case Business.SubscriptionPlan.TRIAL -> now.plusDays(30);
            case Business.SubscriptionPlan.BASIC -> now.plusYears(1);
            case Business.SubscriptionPlan.STANDARD -> now.plusYears(1);
            case Business.SubscriptionPlan.PREMIUM -> now.plusYears(1);
            case Business.SubscriptionPlan.ENTERPRISE -> now.plusYears(2);
            default -> now.plusMonths(1);
        };
    }
    
    /**
     * 更新服务限制
     * @param business 企业信息
     * @param plan 订阅计划
     */
    private void updateServiceLimits(Business business, String plan) {
        switch (plan) {
            case Business.SubscriptionPlan.TRIAL -> {
                business.setApiLimitMonthly(10000L);
                business.setContentLimitMonthly(1000L);
                business.setKeywordLimit(100);
                business.setDataRetentionDays(90);
            }
            case Business.SubscriptionPlan.BASIC -> {
                business.setApiLimitMonthly(50000L);
                business.setContentLimitMonthly(5000L);
                business.setKeywordLimit(500);
                business.setDataRetentionDays(365);
            }
            case Business.SubscriptionPlan.STANDARD -> {
                business.setApiLimitMonthly(200000L);
                business.setContentLimitMonthly(20000L);
                business.setKeywordLimit(2000);
                business.setDataRetentionDays(730);
            }
            case Business.SubscriptionPlan.PREMIUM -> {
                business.setApiLimitMonthly(1000000L);
                business.setContentLimitMonthly(100000L);
                business.setKeywordLimit(10000);
                business.setDataRetentionDays(1095);
            }
            case Business.SubscriptionPlan.ENTERPRISE -> {
                business.setApiLimitMonthly(-1L); // 无限制
                business.setContentLimitMonthly(-1L);
                business.setKeywordLimit(-1);
                business.setDataRetentionDays(-1);
            }
        }
    }
    
    /**
     * ===========================================
     * 工具方法
     * ===========================================
     */
    
    /**
     * 检查企业名称是否存在
     * @param businessName 企业名称
     * @return 是否存在
     */
    private boolean isBusinessNameExists(String businessName) {
        LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Business::getBusinessName, businessName);
        return count(queryWrapper) > 0;
    }
    
    /**
     * 检查统一社会信用代码是否存在
     * @param creditCode 统一社会信用代码
     * @return 是否存在
     */
    private boolean isCreditCodeExists(String creditCode) {
        LambdaQueryWrapper<Business> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Business::getCreditCode, creditCode);
        return count(queryWrapper) > 0;
    }
    
    /**
     * 验证邮箱格式
     * @param email 邮箱
     * @return 是否有效
     */
    private boolean isValidEmail(String email) {
        return email != null && email.matches("^[A-Za-z0-9+_.-]+@(.+)$");
    }
    
    /**
     * 清除企业相关缓存
     * @param businessId 企业ID
     */
    private void clearBusinessCache(String businessId) {
        cacheService.delete("business:info:" + businessId);
        cacheService.deleteByPattern("business:*");
        cacheService.deleteByPattern("stats:*");
    }
    
    /**
     * ===========================================
     * 结果类定义
     * ===========================================
     */
    
    /**
     * 企业注册结果
     */
    public static class BusinessRegistrationResult {
        private boolean success;
        private String message;
        private Business business;
        
        public static BusinessRegistrationResult success(Business business) {
            BusinessRegistrationResult result = new BusinessRegistrationResult();
            result.success = true;
            result.message = "注册成功";
            result.business = business;
            return result;
        }
        
        public static BusinessRegistrationResult failure(String message) {
            BusinessRegistrationResult result = new BusinessRegistrationResult();
            result.success = false;
            result.message = message;
            return result;
        }
        
        // Getters
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public Business getBusiness() { return business; }
    }
    
    /**
     * 企业更新结果
     */
    public static class BusinessUpdateResult {
        private boolean success;
        private String message;
        private Business business;
        
        public static BusinessUpdateResult success(Business business) {
            BusinessUpdateResult result = new BusinessUpdateResult();
            result.success = true;
            result.message = "更新成功";
            result.business = business;
            return result;
        }
        
        public static BusinessUpdateResult failure(String message) {
            BusinessUpdateResult result = new BusinessUpdateResult();
            result.success = false;
            result.message = message;
            return result;
        }
        
        // Getters
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
        public Business getBusiness() { return business; }
    }
    
    /**
     * 认证结果
     */
    public static class VerificationResult {
        private boolean success;
        private String message;
        
        public static VerificationResult success(String message) {
            VerificationResult result = new VerificationResult();
            result.success = true;
            result.message = message;
            return result;
        }
        
        public static VerificationResult failure(String message) {
            VerificationResult result = new VerificationResult();
            result.success = false;
            result.message = message;
            return result;
        }
        
        // Getters
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
    }
    
    /**
     * 订阅结果
     */
    public static class SubscriptionResult {
        private boolean success;
        private String message;
        
        public static SubscriptionResult success(String message) {
            SubscriptionResult result = new SubscriptionResult();
            result.success = true;
            result.message = message;
            return result;
        }
        
        public static SubscriptionResult failure(String message) {
            SubscriptionResult result = new SubscriptionResult();
            result.success = false;
            result.message = message;
            return result;
        }
        
        // Getters
        public boolean isSuccess() { return success; }
        public String getMessage() { return message; }
    }
}